package cn.easyutil.util.platform.jiguang;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.easyutil.util.javaUtil.JsonUtil;
import cn.easyutil.util.javaUtil.StringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import cn.easyutil.util.javaUtil.HttpUtil;

/**
 * 极光推送工具
 * @author spc
 *
 */
public class JiguangPushUtil {

	/** 极光appkey*/
	private String appkey;
	/** 极光masterSecret*/
	private String masterSecret;
	//极光header权限鉴定的key
	private String authKey = "Authorization";
	//极光请求父路径
	private String baseUrl="https://api.jpush.cn/v3/push";
	//标签集合
	private List<String> tagList = new ArrayList<String>();
	//标签强匹配集合
	private List<String> tagAndList = new ArrayList<String>();
	//不匹配的标签集合
	private List<String> tagNotList = new ArrayList<String>();
	//别名集合
	private List<String> aliasList = new ArrayList<String>();
	//registrationId集合
	private List<String> registrationIdsList = new ArrayList<String>();
	//自定义参数
	private Map<String, String> extras = new HashMap<String, String>();
	//推送平台，默认全平台
	private int platformType = 0;
	
	public JiguangPushUtil(String appkey,String masterSecret){
		this.appkey = appkey;
		this.masterSecret = masterSecret;
	}
	
	public static JiguangPushUtil build(String appkey,String masterSecret){
		return new JiguangPushUtil(appkey, masterSecret);
	}
	
	/**
	 * 设置标签
	 * @param tags	标签名称
	 * @return
	 */
	public JiguangPushUtil setTags(String...tags){
		this.tagList.addAll(Arrays.asList(tags));
		return this;
	}
	
	/**
	 * 设置强匹配标签
	 * @param and	强匹配的标签
	 * @return
	 */
	public JiguangPushUtil setTagsAnd(String...and){
		this.tagAndList.addAll(Arrays.asList(and));
		return this;
	}
	
	/**
	 * 设置不匹配的标签
	 * @param not
	 * @return
	 */
	public JiguangPushUtil setTagsNot(String...not){
		this.tagNotList.addAll(Arrays.asList(not));
		return this;
	}
	
	/**
	 * 设置别名匹配
	 * @param alias
	 * @return
	 */
	public JiguangPushUtil setAlias(String...alias){
		this.aliasList.addAll(Arrays.asList(alias));
		return this;
	}
	
	/**
	 * 设置registrationIds集合
	 * @param registrationIds	极光注册的用户唯一标识
	 * @return
	 */
	public JiguangPushUtil setRegistrationIds(String...registrationIds){
		if(registrationIds.length > 1000){
			throw new RuntimeException("一次推送的目标用户不能超过1000个");
		}
		this.registrationIdsList.addAll(Arrays.asList(registrationIds));
		return this;
	}
	
	/**
	 * 设置推送平台
	 * @param platformType	0-全部平台 1-"android" 2-"ios"
	 * @return
	 */
	public JiguangPushUtil setPlatform(Integer platformType){
		if(platformType != null && platformType>=0 && platformType<=2){
			this.platformType = platformType;
		}
		return this;
	}
	
	/**
	 * 添加自定义参数
	 * @param key
	 * @param val
	 * @return
	 */
	public JiguangPushUtil setCustomizeParam(String key,String val){
		this.extras.put(key, val);
		return this;
	}
	
	/**
	 * 发起推送
	 * @param text	推送内容
	 * @param registrationIds	用户在极光的唯一标识
	 */
	public void push(String text,String...registrationIds){
		setRegistrationIds(registrationIds);
		push(text);
	}
	/**
	 * 发起推送
	 * @param text	推送内容
	 */
	public void push(String text){
		push(text,null,null);
	}
	/**
	 * 发送极光推送
	 * @param title	推送标题，可为空
	 * @param text	推送内容,不可为空
	 * @param img	推送图片，可为空
	 */
	public void push(String text,String title,String img){
		//总参数
		Map<String, Object> param = new HashMap<String, Object>();
		//接收者类型  tag(标签),tag_and(强制匹配标签),tag_not(不包含的标签),alias(别名),registration_id(极光注册的用户唯一标识)
		Map<String, Object> audience = new HashMap<String, Object>();
		if(!this.tagList.isEmpty()){
			audience.put("tag", this.tagList);
		}
		if(!this.tagAndList.isEmpty()){
			audience.put("tag_and", this.tagAndList);
		}
		if(!this.tagNotList.isEmpty()){
			audience.put("tag_not", this.tagNotList);
		}
		if(!this.aliasList.isEmpty()){
			audience.put("alias", this.aliasList);
		}
		if(!this.registrationIdsList.isEmpty()){
			audience.put("registration_id", this.registrationIdsList);
		}
		if(audience.isEmpty()){
			throw new RuntimeException("接收者不能为空");
		}
		if(platformType == 0){
			//全部
			param.put("platform", new String[]{"android","ios"});
			param.put("notification", notificationAll(text, title, img));
		}else if(platformType == 1){
			//安卓
			param.put("platform", new String[]{"android"});
			param.put("notification", notificationAndroid(text, title, img));
		}else if(platformType == 2){
			//ios
			param.put("platform", new String[]{"ios"});
			param.put("notification", notificationIos(text, title, img));
		}
		param.put("audience", audience);
		//http请求工具
		HttpUtil util = new HttpUtil();
		//请求极光推送
		util.setRequestUrl(baseUrl);
		util.setRequestMethod("POST");
		util.setJsonRequestParam(param);
		util.setHeaders(authKey, "Basic "+ StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		try {
			util.doUrl();
		} catch (Exception e) {
			throw new RuntimeException("接收者设置不正确或不存在");
		}
	}
	
	private Map<String, Object> notificationAll(String text,String title,String img){
		Map<String, Object> notification = new HashMap<String, Object>();
		notification.putAll(notificationAndroid(text, title, img));
		notification.putAll(notificationIos(text, title, img));
		return notification;
	}
	
	/**
	 * 安卓信息设置
	 * @param text	推送内容为必填
	 * @param title	推送标题
	 * @param img	推送图片
	 * @return
	 */
	private Map<String, Object> notificationAndroid(String text,String title,String img){
		if(StringUtil.isEmpty(text)){
			throw new RuntimeException("推送内容不能为空");
		}
		Map<String, Object> param = new HashMap<String, Object>();
		Map<String, Object> android = new HashMap<String, Object>();
		android.put("alert", text);
		if(!StringUtil.isEmpty(title)){
			android.put("title", title);
		}
		if(!StringUtil.isEmpty(img) && (img.endsWith(".jpg")||img.endsWith(".png"))){
			android.put("style", 3);
			android.put("big_pic_path", img);
		}
		android.put("extras", extras);
		param.put("android", android);
		return param;
		
	}
	
	private Map<String, Object> notificationIos(String text,String title,String img){
		if(StringUtil.isEmpty(text)){
			throw new RuntimeException("推送内容不能为空");
		}
		Map<String, Object> param = new HashMap<String, Object>();
		Map<String, Object> ios = new HashMap<String, Object>();
		ios.put("alert", text);
		ios.put("extras", extras);
		param.put("ios", ios);
		return param;
	}
	
	/**
	 * 修改用户别名(每个用户仅能设置一个别名)
	 * @param registrationId	极光注册的唯一标识
	 * @param alias	别名
	 */
	public void updateAlias(String registrationId,String alias){
		if(StringUtil.isEmpty(alias)){
			throw new RuntimeException("别名不能为空");
		}
		if(StringUtil.isEmpty(registrationId)){
			throw new RuntimeException("registrationId不能为空");
		}
		String url = "https://device.jpush.cn/v3/devices/"+registrationId;
		HttpUtil http = new HttpUtil(url);
		http.setRequestMethod("POST");
		http.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("alias",alias);
		http.setJsonRequestParam(param);
		http.doUrl();
	}
	
	/**
	 * 根据别名获取所有该别名下的用户的极光registrationId
	 * @param alias
	 */
	public List<String> getAliasUsers(String alias){
		if(StringUtil.isEmpty(alias)){
			throw new RuntimeException("别名不能为空");
		}
		String url = "https://device.jpush.cn/v3/aliases/"+alias;
		HttpUtil http = new HttpUtil(url);
		http.setRequestMethod("GET");
		http.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		String result = http.doUrl();
		JSONArray array = JSONObject.parseObject(result).getJSONArray("registration_ids");
		return JsonUtil.jsonToList(JsonUtil.beanToJson(array), String.class);
		
	}
	
	/**
	 * 添加标签
	 * @param registrationId
	 * @param tags
	 */
	public void addTags(String registrationId,String...tags){
		if(tags.length == 0){
			throw new RuntimeException("标签不能为空");
		}
		String url = "https://device.jpush.cn/v3/devices/"+registrationId;
		HttpUtil http = new HttpUtil(url);
		http.setRequestMethod("POST");
		http.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		Map<String, Object> param = new HashMap<String, Object>();
		Map<String, Object> add = new HashMap<String, Object>();
		add.put("add", tags);
		param.put("tags",add);
		http.setJsonRequestParam(param);
		http.doUrl();
	}
	
	/**
	 * 删除标签
	 * @param registrationId
	 * @param tags
	 */
	public void deleteTags(String registrationId,String...tags){
		if(tags.length == 0){
			throw new RuntimeException("标签不能为空");
		}
		String url = "https://device.jpush.cn/v3/devices/"+registrationId;
		HttpUtil http = new HttpUtil(url);
		http.setRequestMethod("POST");
		http.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		Map<String, Object> param = new HashMap<String, Object>();
		Map<String, Object> remove = new HashMap<String, Object>();
		remove.put("remove", tags);
		param.put("tags",remove);
		http.setJsonRequestParam(param);
		http.doUrl();
	}
	
	/**
	 * 获取极光用户信息
	 * @param registrationId
	 * @return
	 */
	public JiguangPushUser getJiguangUser(String registrationId){
		String url = "https://device.jpush.cn/v3/devices/"+registrationId;
		HttpUtil http = new HttpUtil(url);
		http.setRequestMethod("GET");
		http.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		String result = http.doUrl();
		JSONObject obj = JSONObject.parseObject(result);
		JiguangPushUser user = new JiguangPushUser();
		user.setRegistrationId(registrationId);
		user.setAlias(obj.getString("alias"));
		user.setMobile(obj.getString("mobile"));
		JSONArray array = obj.getJSONArray("tags");
		user.setTags(JsonUtil.jsonToList(JsonUtil.beanToJson(array), String.class));
		return user;
	}
	
	public static void main(String[] args) {
		
	}
	
	class JiguangPushUser{
		private String registrationId;
		private List<String> tags;
		private String alias;
		private String mobile;
		public String getRegistrationId() {
			return registrationId;
		}
		public void setRegistrationId(String registrationId) {
			this.registrationId = registrationId;
		}
		public List<String> getTags() {
			return tags;
		}
		public void setTags(List<String> tags) {
			this.tags = tags;
		}
		public String getAlias() {
			return alias;
		}
		public void setAlias(String alias) {
			this.alias = alias;
		}
		public String getMobile() {
			return mobile;
		}
		public void setMobile(String mobile) {
			this.mobile = mobile;
		}
		
		
	}
}
